# Technical Deep Dive 8 - Looking Inside The App And Firmware

## Core Question
What really happens between a browser click and a physical hardware change, and why does software structure matter so much in an embedded project?

## The System Is Split Across Multiple Layers
This project is not one monolithic program. It is a coordinated system with multiple layers:

- browser UI
- browser transport and rendering logic
- firmware transport receive path
- firmware command parsing and dispatch
- hardware control routines
- MCU peripheral and electrical behaviour

Each layer has a different responsibility.

## A Browser Click Does Not Directly Change Hardware
A useful concrete example is the `Hello World` button in the dashboard. In the UI, it is just a normal browser control. In JavaScript, that click becomes a command string such as `HELLO_WORLD`.

Architecturally, that means:
- the browser does not manipulate GPIO directly
- it emits an agreed command string
- that string becomes part of a transport protocol between browser and MCU

This separation matters because UI concerns stay separate from hardware concerns.

## Transport Serialises The Command
The browser transport layer converts the JavaScript string into bytes, appends line termination, and writes the data into the serial stream.

Important ideas:
- strings become bytes
- line endings help define command boundaries
- transport does not decide command semantics

This project intentionally uses a text command protocol because it is easy to inspect, debug, log, and teach.

## USB CDC Moves Bytes, Not Meaning
On the microcontroller side, the USB CDC layer receives packets and buffers bytes until a complete line has arrived.

That is a crucial design boundary:
- USB receive code performs framing
- application command code performs interpretation

So the transport layer answers the question, "Did we receive a complete command line?" It does not answer, "What should the board do?"

## Stream Processing Rebuilds Logical Commands
Firmware receives a stream, not a guaranteed one-command-per-packet message. Stream processing therefore converts incoming bytes into full command lines before handing them to the parser.

This is robust embedded design because packet boundaries and logical message boundaries are not the same thing.

## The Command Registry Defines The Vocabulary
Once a full line exists, the command system compares it against a formal registry of supported commands.

That registry gives the project a vocabulary. Some commands are exact matches. Others are prefix commands followed by arguments.

This is important because a command system is not just a pile of string comparisons. It is a contract that defines what the system is willing to understand.

## Dispatch Turns Text Into Behaviour
After parsing, the firmware dispatches the command to the appropriate routine. At this point the system moves from protocol meaning into application behaviour.

Examples:
- LED commands
- mode changes
- display updates
- sensor requests
- animation control

This is the boundary where the command stops being text and becomes a decision about program behaviour.

## HAL And GPIO Form The Hardware Abstraction Boundary
If the command eventually changes an LED or other digital output, the application code calls lower-level helpers such as STM32 HAL GPIO functions.

That means the stack now looks like this:
- UI decides what to request
- protocol carries the request
- parser identifies the request
- firmware logic decides the behaviour
- HAL translates that behaviour into peripheral-level operations

This is why hardware abstraction layers matter. They let application code express intent without manually rewriting every register operation at the call site.

## GPIO Configuration Defines What The Pin Is Allowed To Do
A GPIO write only works because startup code already configured that pin into an appropriate mode. Without the earlier GPIO initialisation step, the later write call would not have the intended electrical meaning.

This is a deep embedded lesson: runtime behaviour depends on earlier system configuration.

## The Electrical Layer Still Matters
At the electrical level, software is not "lighting an LED" in a magical sense. The MCU output driver changes the pin state, which changes whether current can flow through the external circuit.

So a full explanation of the event chain includes:
- software intent
- transport framing
- parser/dispatcher logic
- peripheral abstraction
- electrical state change

That is the real meaning of "browser click to GPIO."

## Structure Reduces Cognitive Load
Large systems become unmanageable if everything is mixed together. Structure helps answer questions such as:

- where is the protocol defined?
- where are display rules handled?
- where does hardware control happen?
- what part owns state?
- what part only moves data?

This is why separation of concerns matters so much in professional software and firmware.

## Debugging Depends On Structure
When something goes wrong, good boundaries help isolate the failure:

- UI bug?
- transport bug?
- framing bug?
- parser bug?
- hardware bug?
- GPIO configuration bug?

Without clear boundaries, debugging becomes guesswork.

## Flash, RAM, Regions, And Sections
This lesson also naturally connects to memory.

Flash holds persistent program content such as:
- executable code
- constant strings
- lookup tables
- interrupt vectors

RAM holds runtime content such as:
- mutable variables
- telemetry buffers
- parser buffers
- stack and heap working space

The linker places sections such as `.text`, `.rodata`, `.data`, and `.bss` into larger memory regions such as `FLASH` and `RAM`.

That means software structure is not just an organisational issue. It also has physical consequences in the memory map.

## Build Analysis As Architecture Feedback
A memory report is not just a build artifact. It is engineering feedback.

- growing `.text` means more code in flash
- growing `.rodata` often means more fixed text or constant data
- growing `.bss` often means more runtime buffers or large state objects
- growing stack or heap reservations reduces remaining RAM headroom

This is one reason embedded systems engineering feels concrete. Design choices become visible in measurable resource usage.

## App-Side Platform Features
The dashboard also contains features that are deliberately app-side rather than firmware-side, such as automation logic and live feed formatting.

That split is important:
- firmware owns hardware timing, device control, and command parsing
- the browser app can own richer editing, conditions, external data formatting, and UI workflows

A good architecture chooses the correct side for each job.

## Why This Matters
This lesson moves students from using a system to reasoning about a system. That is a major step toward real engineering practice.

When students can explain both the browser-click-to-GPIO chain and the flash/RAM consequences of software structure, they are no longer just operating the project. They are beginning to understand how it is engineered.
